package serialport


import event.*
import ext.*
import manager.AppManager
import manager.StatusManager
import mvc.model.Status
import org.greenrobot.eventbus.EventBus

class DeliverPortManager : Thread() {
    companion object {
        val Instance: DeliverPortManager by lazy { DeliverPortManager() }
    }

    var deliverPort: Port? = null
    var runnFlag = false

    private val deliverBuffer = ByteArray(64)
    private var index = 0

    init {
        try {
            deliverPort = Port(AppManager.deliverPortName)
            log("出货串口:${AppManager.deliverPortName}-打开成功")
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun write(bytes: ByteArray) {
        val ret = bytes.toHexString()
        log(ret, "串口发送")
        deliverPort?.write(bytes)
    }

    override fun start() {
        runnFlag = true
        super.start()
    }

    private fun onDeliverPortRecv(d: Byte) {
        if (d == 0xE1.toByte()) {
            index = 0
        }

        if (index >= deliverBuffer.size) {
            return
        }

        deliverBuffer[index++] = d

        if (d == 0xEF.toByte()) {
            if (index < 5) {
                return
            }
            val bytes = ByteArray(index)
            System.arraycopy(deliverBuffer, 0, bytes, 0, index)
            index = 0
            if (bytes.isChecked()) {
                val ret = bytes.toHexString()
                log(ret, "串口数据接收")
                onParse(bytes)
            }
        }
    }

    private fun onParse(bytes: ByteArray) {
        EventBus.getDefault().post(SerialPortReceiveEvent(bytes))

        val action = bytes.action()

        when (action) {
            0x83 -> {
                val env = ScanResultEvent.withByteArray(bytes)
                EventBus.getDefault().post(env)
            }

            0x84 -> {
                val env = DeliveryResultEvent.withByteArray(bytes)
                EventBus.getDefault().post(env)
            }

            0x85 -> {
                val env = DeliveryScanResultEvent.withByteArray(bytes)
                EventBus.getDefault().post(env)
            }

            0x86 -> {
                val status = Status(bytes)
                StatusManager.refresh(status)
                EventBus.getDefault().post(StatusChangedEvent(status))
            }

            0x90 -> {
                val env = GoodsTypeQueryResultEvent.withByteArray(bytes)
                EventBus.getDefault().post(env)
            }

            0xB0 -> {
                val env = CargoEvent(bytes.byteArg(1),
                bytes.byteArg(2), bytes.byteArg(3))
                EventBus.getDefault().post(env)
            }
        }

    }

    override fun run() {
        if (deliverPort == null) {
            return
        }

        var len = 0
        val bytes = ByteArray(64)
        while (runnFlag) {
            len = deliverPort!!.read(bytes)

            if (len > 0) {
                for (i in 0 until len) {
                    onDeliverPortRecv(bytes[i])
                }
            }
        }
    }

}
